package com.lihang.system.controller;

import com.lihang.common.vo.*;
import com.lihang.system.dto.request.StudentRequest;
import com.lihang.system.entity.*;
import com.lihang.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.RoundingMode;
import java.sql.Time;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生表 前端控制器
 * </p>
 *
 * @author lihang
 * @since 2023-04-15
 */
@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private IStudentService iStudentService;
    @Autowired
    private IParentsService iParentsService;
    @Autowired
    private IStuCourseService iStuCourseService;
    @Autowired
    private IStudyService iStudyService;
    @Autowired
    private IScholarshipService iScholarshipService;
    @Autowired
    private ICompetitionService iCompetitionService;
    @Autowired
    private IZhuXueJinService iZhuXueJinService;
    @Autowired
    private IZhuXueDaiService iZhuXueDaiService;
    @Autowired
    private IQinGongZhuXueService iQinGongZhuXueService;
    @Autowired
    private IPunishmentRecordService iPunishmentRecordService;
    @Autowired
    private IExtracurricularActivitiesService iExtracurricularActivitiesService;
    @Autowired
    private IInstructionService iInstructionService;
    @Autowired
    private IDorRewardsAndPunishmentService iDorRewardsAndPunishmentService;
    @Autowired
    private IDorTimeWrongService iDorTimeWrongService;

    /**
     * 学生查询
     */
    @GetMapping(value = "/stuSchSimple")
    public Result<List<StudentVo>> queryStudents(String name) {
       /* Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        List<Student> list = iStudentService.listByMap(map);
        return Result.success(list);*/
        List<StudentVo> list = iStudentService.queryStudents(name);
        return Result.success(list);
    }

    /**
     * 学生列表查询
     */
    @PostMapping(value = "/stuSchAdvanced")
    public Result<List<StudentVo>> queryStudentList(@RequestBody StudentRequest param) {
        List<StudentVo> list = iStudentService.queryStudentList(param);
        return Result.success(list);
    }

    /**
     * 个人信息
     */
    @GetMapping(value = "/stuInfo/{stuId}")     //通过路径传递参数，是更规范的写法
    public Result<StuInfoVo> queryStudentById(@PathVariable Integer stuId) {   //通过路径传参，注解用@PathVariable；不通过路径传参，注解用@RequestParam
        //学生信息
        Student student = iStudentService.queryStudentById(stuId);
        //父母信息
        List<Parents> parents = iParentsService.queryStudentById(stuId);
       /* StuInfoVo stuInfoVo = new StuInfoVo();
        stuInfoVo.setStudent(student);
        stuInfoVo.setParents(parents);*/
        StuInfoVo build = StuInfoVo.builder().student(student).parents(parents).build();
        return Result.success(build);
    }

    /**
     * 学习科研
     */
    @GetMapping(value = "/studyLearning/{stuId}")
    public Result<StudyLearningVo> studyLearningResult(@PathVariable Integer stuId){
        /* 课程信息 */
        List<StuCourse> stuCourses = iStuCourseService.stuCourse(stuId);
        Map<Integer, List<StuCourse>> collectCNum = stuCourses.stream().collect(Collectors.groupingBy(StuCourse::getStuId));
        Map<List<Integer>, List<StuCourse>> collectPassCNum = stuCourses.stream().collect(Collectors.groupingBy( stuCourse -> Arrays.asList(stuCourse.getStuId(), stuCourse.getRetake())));

        /* 科研信息 */
        List<Study> studies = iStudyService.study(stuId);
        Map<Integer, List<Study>> collect1 = studies.stream().collect(Collectors.groupingBy(Study::getType));
       // studies.size();
        Integer retake = 0; //  局部变量retake，用于判断是否重修
        StudyLearningVo studyLearningVo = StudyLearningVo.builder()./*student(headInfo).*/studies(studies).stuCourses(stuCourses)
                .CNum(CollectionUtils.isEmpty(collectCNum.get(stuId))?0:collectCNum.get(stuId).size())
                .PassCNum(CollectionUtils.isEmpty(collectPassCNum.get(Arrays.asList(stuId,retake))) ? 0 : collectPassCNum.get(Arrays.asList(stuId, retake)).size())
                .lunWenNum(CollectionUtils.isEmpty(collect1.get(1))?0:collect1.get(1).size())
                .zhuZuoNum(CollectionUtils.isEmpty(collect1.get(2))?0:collect1.get(2).size())
                .zhuanLiNum(CollectionUtils.isEmpty(collect1.get(3))?0:collect1.get(3).size())
                .ruanZhuNum(CollectionUtils.isEmpty(collect1.get(4))?0:collect1.get(4).size())
                .build();
        /* 对学分求和并输出 */
        double sum = stuCourses.stream().mapToDouble(StuCourse::getCredit).sum();   //lambda表达式
        /*double sumCredit = 0;
        for (StuCourse stuCourse : stuCourses) {
            sumCredit = sumCredit + Double.parseDouble(stuCourse.getCredit().toString());
        }*/
        studyLearningVo.setCredit(String.valueOf(sum));
        /* 通过率 */
        List<StuCourse> collect = stuCourses.stream().filter(p -> 0==p.getRetake()).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(collect)){
            studyLearningVo.setPassingRate("0%");
        }else {
            studyLearningVo.setPassingRate(accuracy(collect.size(),stuCourses.size(),1));
        }
        /* 计算平均绩点 */
        double sum1 = stuCourses.stream().mapToDouble(p -> p.getCredit() * p.getGp()).sum();
//        studyLearningVo.setGpAvg(String.valueOf(sum1/sum));
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        String gpAvg = decimalFormat.format( sum1 / sum);
        studyLearningVo.setGpAvg(gpAvg);

        //方法：1、lambda表达式groupby；2、lambda表达式filter(p ->  ==p.getType);
        return Result.success(studyLearningVo);
    }//非常amazing啊，这个返回类搞得我很是难受，求解决。//还有
    public static String accuracy(double num, double total, int scale){
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        //精确几位小数
        df.setMaximumFractionDigits(scale);
        //模式 （四舍五入）
        df.setRoundingMode(RoundingMode.HALF_UP);
        double accuracy_num = num / total * 100;
        return df.format(accuracy_num)+"%";
    }

    /**
     *奖惩助贷
     */
    @GetMapping(value = "/jiangChengZhuDai/{stuId}")
    public Result<JiangChengZhuDaiVo> jiangChengZhuDai(@PathVariable Integer stuId) {
        /*奖学金*/
        List<Scholarship> scholarships = iScholarshipService.queryScholorship(stuId);
        double scholarshipsSum = scholarships.stream().mapToDouble(p -> p.getAmount()).sum(); // 统计奖学金总额

        /*竞赛*/
        List<Competition> competitions = iCompetitionService.queryCompetition(stuId);

        /*助学金*/
        List<ZhuXueJin> zhuXueJins = iZhuXueJinService.queryZhuXueJin(stuId);
        double zhuXueJinsSum = zhuXueJins.stream().mapToDouble(ZhuXueJin::getAmount).sum(); //  统计助学金总额

        /*助学贷*/
        List<ZhuXueDai> zhuXueDais = iZhuXueDaiService.queryZhuXueDai(stuId);
        double zhuXueDaiSum = zhuXueDais.stream().mapToDouble(ZhuXueDai::getAmount).sum();
        double zhuXueDai_1 = zhuXueDais.stream().mapToDouble(ZhuXueDai::getFaFang).sum();
        double zhuXueDai_0 = zhuXueDais.stream().mapToDouble(ZhuXueDai::getRepayment).sum();

        /*勤工助学*/
        List<QinGongZhuXue> qinGongZhuXues = iQinGongZhuXueService.queryQinGongZhuXue(stuId);
        double qinGongZhuXuesSum = qinGongZhuXues.stream().mapToDouble(p -> p.getAountOfTime()).sum();
        Map<String, List<QinGongZhuXue>> qinGongZhuXueTime = qinGongZhuXues.stream().collect(Collectors.groupingBy(QinGongZhuXue::getGangWei));

        /*惩处信息*/
        List<PunishmentRecord> punishmentRecords = iPunishmentRecordService.queryPunishmentRecord(stuId);
        Map<Integer, List<PunishmentRecord>> collect = punishmentRecords.stream().collect(Collectors.groupingBy(PunishmentRecord::getType));

        JiangChengZhuDaiVo jiangChengZhuDai = JiangChengZhuDaiVo.builder()  // 如何把很多数据打包进返回类
                .scholarshipsTime(scholarships.size())  // 奖学金返回
                .scholarshipsSum(String.valueOf(scholarshipsSum))
                .scholarships(scholarships)
                .competitionsTime(competitions.size())  //  竞赛返回
                .competitions(competitions)
                .zhuXueJinsTime(zhuXueJins.size())  //  助学金返回
                .zhuXueJinsSum(String.valueOf(zhuXueJinsSum))
                .zhuXueJins(zhuXueJins)
                .zhuXueDaiSum(String.valueOf(zhuXueDaiSum))//  助学贷返回
                .zhuXueDai_1(String.valueOf(zhuXueDai_1))
                .zhuXueDai_0(String.valueOf(zhuXueDai_0))
                .zhuXueDais(zhuXueDais)
                .qinGongZhuXuesSum(String.valueOf(qinGongZhuXuesSum))   //勤工助学返回
//                .gangWei()
//                .qinGongZhuXuesTime(qinGongZhuXues.size())
                .qinGongZhuXuesTime(qinGongZhuXueTime.size())
                .qinGongZhuXues(qinGongZhuXues)
                .warnTime(CollectionUtils.isEmpty(collect.get(1))?0:collect.get(1).size())
                .jgTime(CollectionUtils.isEmpty(collect.get(2))?0:collect.get(2).size())    // 惩处信息返回
                .yzjgTime(CollectionUtils.isEmpty(collect.get(3))?0:collect.get(3).size())
                .lxckTime(CollectionUtils.isEmpty(collect.get(4))?0:collect.get(4).size())
                .punishmentRecords(punishmentRecords)
                .build();
        return Result.success(jiangChengZhuDai);
    }
    /*public List<String> getNameList(List<QinGongZhuXue> aList){
        List<String> gangWeiList = new ArrayList<>();
        for (QinGongZhuXue qinGongZhuXue : aList){
            gangWeiList.add(qinGongZhuXue.getGangWei());
        }
        return gangWeiList;
    }*/

    /**
     * 第二课堂
     */
    @GetMapping(value = "/diErKeTang/{stuId}")
    public Result<DiErKeTangVo> diErKeTangResult(@PathVariable Integer stuId) {
        /*顶头个人*/
//        Student student = iStudentService.queryById(stuId);
        /*活动成长*/
        List<ExtracurricularActivities> extracurricularActivities = iExtracurricularActivitiesService.queryExtracurricularActivities(stuId);
        double scoreSum = extracurricularActivities.stream().mapToDouble(p -> p.getScore()).sum();
        List<ExtracurricularActivities> collect = extracurricularActivities.stream().filter(p -> p.getDate().getYear() == LocalDate.now().getYear()).collect(Collectors.toList());
        double scoreSumNow = collect.stream().mapToDouble(p -> p.getScore()).sum();
        /*深度辅导*/
        List<Instruction> instructions = iInstructionService.queryInstructionService(stuId);
        List<ExtracurricularActivities> instructionscollect = extracurricularActivities.stream().filter(p -> p.getDate().getYear() == LocalDate.now().getYear()).collect(Collectors.toList());
        DiErKeTangVo diErKeTang = DiErKeTangVo.builder()
                .extracurricularActivities(extracurricularActivities)
                .instructionsTimeNow(instructionscollect.size())
                .instructionsTime(instructions.size())
                .scoreSum(String.valueOf(scoreSum))
                .scoreSumNow(String.valueOf(scoreSumNow))
                .scoreTimeNow(collect.size())
                .scoreTime(extracurricularActivities.size())
                .instructions(instructions).build();
        return Result.success(diErKeTang);
    }

    /**
     * 书院信息
     */
    @GetMapping(value = "/dorInfo/{stuId}")
    public Result<DorInfoVo> dorInfoResult(@PathVariable Integer stuId) {
        /*顶头个人信息*/
        Student student = iStudentService.queryById(stuId);
        /*宿舍奖惩*/
        List<DorRewardsAndPunishment> dorRewardsAndPunishments = iDorRewardsAndPunishmentService.queryDorRewardsAndPunishment(stuId);
        Map<Integer,List<DorRewardsAndPunishment>> RW = dorRewardsAndPunishments.stream()
                .collect(Collectors.groupingBy(DorRewardsAndPunishment::getType));
        /*宿舍晚归未归*/
        List<DorTimeWrong> dorTimeWrongs = iDorTimeWrongService.queryDorTimeWrong(stuId);
//      Map<List<Integer>, List<DorTimeWrong>> wanOrWei = dorTimeWrongs.stream().filter(dorTimeWrong -> dorTimeWrong.getDate().getYear() == LocalDate.now().getYear()).collect(Collectors.groupingBy( dorTimeWrong -> Arrays.asList(dorTimeWrong.getStuId(), dorTimeWrong.getType())));
        Map<Integer, List<DorTimeWrong>> wanOrWei = dorTimeWrongs.stream()
//                .filter(p -> p.getDate().getYear() == LocalDate.now().getYear())
                .collect(Collectors.groupingBy(DorTimeWrong::getType));
        /*舍友信息*/
        List<Student> students = iStudentService.queryByRoomId(student.getDorNum(), stuId);
        List<DorTimeWrong> collect = dorTimeWrongs.stream()
                .filter(p -> Integer.parseInt(new SimpleDateFormat("yyyy").format(p.getDate())) == LocalDate.now().getYear() && stuId.equals(p.getStuId()))
                .collect(Collectors.toList());

        double average = collect.stream().mapToLong(p -> p.getDate().getTime()).average().getAsDouble();
        DorInfoVo dorInfoVo = DorInfoVo.builder()
                .jingGao(RW.get(0).size())
                .huoJiang(RW.get(1).size())
                .backTime(convertTimestampToDate((long) average))
                .wanGui(wanOrWei.get(1).size())
                .weiGui(wanOrWei.get(2).size())
                .roomieInfo(students)
                .dorRewardsAndPunishments(dorRewardsAndPunishments)
                .dorTimeWrongs(dorTimeWrongs)
                .build();
        return Result.success(dorInfoVo);
    }
    public static String convertTimestampToDate(long timestamp) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
        Date date = new Date(timestamp);
        return dateFormat.format(date);
    }
    public static void main(String[] args) {
        System.out.println(new Date().getTime());
        System.out.println(System.currentTimeMillis());
    }

    /**
     * 书院信息——折线图
     * @param stuId
     * @return
     */
    @GetMapping(value = "/zheXianTu/{stuId}")
    public Result<List<ZheXianTuVo>> zheXianTuVos(@PathVariable Integer stuId){
        List<ZheXianTuVo> dorTimeWrongs = iDorTimeWrongService.queryZheXianTu(stuId);
        return Result.success(dorTimeWrongs);
    }
    /**
     * 书院信息——柱状图
     *
     * 这个接口
     * 1。所有学生平均时间
     * 2。学生每学年返回时间
     */
    @GetMapping(value = "/zhuZhuangTu/{stuId}")
    public Result<ZhuZhuangTu> zhuZhuangTuResult(@PathVariable Integer stuId){
        List<ZheXianTuVo> avgAll = iDorTimeWrongService.zhuzhuangtuAvgAll();
        List<ZheXianTuVo> avgs = iDorTimeWrongService.zhuzhuangtuAvgByNo(stuId);
        ZhuZhuangTu zhuZhuangTu = new ZhuZhuangTu();
        zhuZhuangTu.setAllDate(avgAll.get(0).getTime());
        zhuZhuangTu.setDates(new ArrayList<>());
        for (ZheXianTuVo z:avgs) {
            zhuZhuangTu.getDates().add(z.getTime());
        }
        return Result.success(zhuZhuangTu);
    }
    /**
     * 顶头信息
     */
    @GetMapping(value = "/headInfo/{stuId}")
    public Result<HeadInfo> headInfo(@PathVariable Integer stuId){
        /*顶头个人信息*/
        Student student = iStudentService.queryById(stuId);
        HeadInfo headInfo = new HeadInfo();
        BeanUtils.copyProperties(student,headInfo); //
        return Result.success(headInfo);
    }
}
